package com.src.xyzk.bluetooth.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.UUID;

import com.src.xyzk.bluetooth.BluetoothDeviceListActivity;
import com.src.xyzk_personal.config.Common;
import com.src.xyzk_personal.config.Commonfunc;
import com.src.xyzk_personal.config.LogFile;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.util.Log;

public class BluetoothAdapterService{
	//debug
	private static final String TAG = "BluetoothAdapterService";
	private static final boolean D = true;
	public final BluetoothAdapterService context = BluetoothAdapterService.this;
	private Handler m_handler = null;
	// 定义蓝牙UUID
	private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
	//蓝牙adapter

	private static BluetoothAdapter m_adapter = null; // 蓝牙绑定操作类
	//蓝牙连接线程
	private ConnectThread m_connect_thread = null; // 蓝牙连接线程
	//private ConnectedThread m_connected_thread = null; // 蓝牙通讯监听线程
	private static  BluetoothSocket m_socket = null;
	private static InputStream m_in_stream = null;
	private static OutputStream m_out_stream = null;
	//蓝牙状态对象
	public static BlueStateEvent m_blue_state = null;
	public boolean exit = false;
	private boolean m_record  = false;  //LOG记录开关
	public LogFile m_log = LogFile.getInstance();	//日志对象

	//单例初始化
	private static BluetoothAdapterService m_bluetooth_service = null;
	//单例实现
	public synchronized static BluetoothAdapterService getInstance()
	{
		if (m_bluetooth_service == null)
		{
			m_bluetooth_service = new BluetoothAdapterService();
		}
		return m_bluetooth_service;
	}
	//类构造方法
	private BluetoothAdapterService()
	{
		m_adapter = BluetoothAdapter.getDefaultAdapter();
		m_blue_state = new BlueStateEvent(); //初始化蓝牙状态类
		exit = false;
	}
	public void Sethandler(Handler handler)
	{
		m_handler = handler;
	}
	public void SaveLogData(int mode,String data)
	{
		if(m_log != null){
			m_log.PrintAppend(mode,data);
		}
	}
	/* ---------------------------接口方法(开始)-----------------------------------*/
	//参数为蓝牙MAC地址,长度为17位。格式为：“00:00:00:00：00:00”
	public boolean ConnectDevice(String deviceAddr)
	{
		//如果正在连接，则直接返回false
		if(m_blue_state.IsConnecting())
			return false;
		BluetoothDevice v_device = m_adapter.getRemoteDevice(deviceAddr);
		//设备初始化失败，也返回false
		if(v_device == null)
			return false;
		//启动连接线程
		m_connect_thread = new ConnectThread(v_device);
		m_connect_thread.start();
		//设置状态
		m_blue_state.SetConnecting();
		return true;
	}
	//停止蓝牙服务
	public void StopService()
	{
		if(D) Log.i(TAG,"结束蓝牙服务!");
		m_blue_state.SetListen();
		try
		{
			if(m_socket != null)
			{
				m_socket.close();
				m_socket = null;
			}
			if(m_in_stream != null)
			{
				m_in_stream.close();
				m_in_stream = null;
			}
			if(m_out_stream != null)
			{
				m_out_stream.close();
				m_out_stream = null;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	void exit()
	{
		if(Common.Debug) Log.e(TAG,"执行了exit");
		exit = true;
	}
	//毫秒
	private void Sleep(int times)
	{
		try {
			Thread.sleep(times, 0);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//设置开始记录
	public void SetStartRecord(String vin)
	{
		char first = vin.charAt(0);
		if(first < 'A' || first > 'Z') return;
		if(m_log != null)
		{
			m_record = true;
			if(Common.Debug) Log.i(TAG,"开始记录日志!");
		}
		else
		{
			if(Common.Debug) Log.e(TAG,"创建记录日志失败!");
		}
	}
	/* ---------------------------接口方法(结束)-----------------------------------*/
	/****************************蓝牙连接线程***************************************/
	private class ConnectThread extends Thread
	{
		private  BluetoothDevice v_device = null;
		public ConnectThread(BluetoothDevice device)
		{
			v_device = device;
			try
			{
				m_socket = v_device.createRfcommSocketToServiceRecord(MY_UUID);
			}
			catch (IOException e)
			{
				Log.e(TAG, "create() Blue Socket failed", e);
			}
		}
		public void run()
		{
			Log.i(TAG, "BEGIN mConnectThread");
			setName("ConnectThread");
			//取消搜索
			m_adapter.cancelDiscovery();
			try
			{
				//建立连接....
				Log.i(TAG, "连接Socket");
				m_socket.connect();
				m_in_stream = m_socket.getInputStream();
				m_out_stream = m_socket.getOutputStream();
			}
			catch (IOException e)
			{
				ConnectThreadFailed();
				//关闭Socket
				try
				{
					m_socket.close();
				}
				catch (IOException e2)
				{
					Log.e(TAG, "unable to close() socket during connection failure", e2);
				}
				Log.i(TAG, "连接失败!");
				m_handler.obtainMessage(BluetoothDeviceListActivity.HAND_RECEIVE_CONNECT,0,0).sendToTarget();
				return;
			}
			Log.i(TAG, "连接成功!");

			m_blue_state.SetConnected();
			m_handler.obtainMessage(BluetoothDeviceListActivity.HAND_RECEIVE_CONNECT,1,0).sendToTarget();
		}
	}
	//连接失败处理方法
	private void ConnectThreadFailed()
	{
		m_blue_state.SetListen();
	}
	/****************************蓝牙通信方法(start)***************************************/
	//组合命令
	private int addData2Cmd(byte [] cmd,byte [] Pdata,int Plen,byte [] Pcmdbuf)
	{
		int cmdlen = 0;
		//这里组成发送的命令
		//先添加发送帧头
		Pcmdbuf[0] = 0x55;
		Pcmdbuf[1] = (byte) 0xAA;
		Pcmdbuf[2] = (byte) 0xC1;
		Pcmdbuf[3] = (byte) 0xB1;
		//计算长度
		cmdlen = 4 + 2 + 2 + Plen + 1;
		//填入长度字节
		Pcmdbuf[4] = (byte) ((cmdlen - 6) / 0x100);
		Pcmdbuf[5] = (byte) ((cmdlen - 6) % 0x100);
		//填入命令字
		Pcmdbuf[6] = cmd[0];
		Pcmdbuf[7] = cmd[1];
		//填入DATA
		for(int i = 0; i < Plen; i ++)
		{
			Pcmdbuf[8+i] = Pdata[i];
		}
		//计算校验
		Pcmdbuf[cmdlen - 1] = Commonfunc.CalcChechSum(Pcmdbuf,4,cmdlen - 1);
		return cmdlen;
	}
	//发送数据，发一次收一次
	private int SendOneToOne(byte[] Psend,int Plen,byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		if(m_out_stream == null || m_in_stream == null) return -1; //未连接
		try {
			if(m_in_stream.available() > 0)  //先清除数据
				m_in_stream.read(Precv, 0, m_in_stream.available());
			Sleep(1);
			m_out_stream.write(Psend, 0, Plen);
			Sleep(1);
			m_out_stream.flush();
			Sleep(20);
			if(Common.Debug) Log.i(TAG,"Send:" + Commonfunc.bytesToHexString(Psend, 0,Plen));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(Common.Debug) Log.e(TAG,"Send异常");
		}
		len = Readdata(Precv,Psize,maxtime);
		return len;
	}
	//发送数据，发一次收一次
	private int SendOneToOneNew(byte[] Psend,int Plen,byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		if(m_out_stream == null || m_in_stream == null) return -1; //未连接
		try {
			if(m_in_stream.available() > 0)  //先清除数据
				m_in_stream.skip( m_in_stream.available());
			m_out_stream.write(Psend, 0, Plen);
			m_out_stream.flush();
			Sleep(5);
			//if(Common.Debug) Log.i(TAG,"Send:" + Commonfunc.bytesToHexString(Psend, 0,Plen));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//if(Common.Debug) Log.e(TAG,"Send异常");
		}
		len = ReaddataComplete(Precv,Psize,maxtime);
		return len;
	}
	public String getFilePaths(){
		return m_log.getFilePath();
	}
	public String GetLogfileName()
	{
		//去掉LOG标志
		int v_adr = m_log.m_filename.indexOf("LOG");
		String v_name = null;
		if(v_adr > 0 && v_adr < 100)
			v_name = m_log.m_filename.substring(v_adr + 4);
		return v_name;
	}
	private int ReaddataComplete(byte[] Precv,int Psize,int maxtime)
	{
		int readlen = 0;
		int all_len = 0;
		int datalen = 0;
		if(m_out_stream == null || m_out_stream == null)
		{
			if(Common.Debug) Log.e(TAG,"Readdata exit 1");
			return -1; //断线
		}
		try {
			long starttime = System.currentTimeMillis(); //获得起始时间
			long endtime = starttime;
			while(true)
			{
				Sleep(2);
				if(m_out_stream == null || m_in_stream == null  || exit == true)
				{
					//if(Common.Debug) Log.e(TAG,"Readdata exit 2" + "dout=" + m_out_stream + ";din=" + m_in_stream + ";exit=" + exit);
					break; //未连接
				}
				Sleep(2);
				readlen = m_in_stream.available();
				if((readlen + all_len) >= 9)
				{
					if(datalen == 0) //开始
					{
						m_in_stream.read(Precv,0,6);
						all_len += 6;
						if(((Precv[0]&0xFF) == 0x55) && ((Precv[1]&0xFF) == 0xAA))  //得到头
						{
							datalen = ((Precv[4]&0xFF) << 8) + (Precv[5]&0xFF);
							if(datalen <= (readlen - 6)) //有完整数据,取数据返回
							{
								readlen = m_in_stream.read(Precv,all_len,datalen);
								if(readlen == datalen) //ok返回
								{
									all_len += datalen;
									break;
								}
								else //清空
								{
									all_len = 0;
									datalen = 0;
								}
							}
							else //无完整数据
							{
								if(datalen < 3) //error,或者无效数据
								{
									all_len = 0;
									datalen = 0;
								}
							}
						}
						else //无效数据
						{
							all_len = 0;
							datalen = 0;
						}
					}
					else
					{
						if(readlen >= datalen) //数据全了
						{
							readlen = m_in_stream.read(Precv,all_len,datalen);
							if(readlen == datalen) //ok返回
							{
								all_len += datalen;
								break;
							}
							else //清空
							{
								all_len = 0;
								datalen = 0;
							}
						}
					}
				}
				endtime = System.currentTimeMillis();
				if(endtime  > (starttime + maxtime)) //超时
				{
					if(Common.Debug) Log.i(TAG,"超时退出!");
					all_len = -2; //超时
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			all_len = -3; //IO异常
			if(Common.Debug) Log.e(TAG,"接收异常");
		}
		//计算校验
		if(all_len > 1)
		{
			if(Precv[all_len - 1] != Commonfunc.CalcChechSum(Precv, 4, all_len - 1)) //nok
				all_len = -4; //校验失败
		}
		return all_len;
	}
	//只收数据,保证收到完整帧
	private int Readdata(byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		int all_len = 0;
		byte [] buf = new byte[256];
		if(m_out_stream == null || m_out_stream == null)
		{
			if(Common.Debug) Log.e(TAG,"Readdata exit 1");
			return -1; //未连接
		}
		try {
			long starttime = System.currentTimeMillis(); //获得起始时间
			long endtime = starttime;
			while(true)
			{
				Sleep(5);
				if(m_out_stream == null || m_in_stream == null  || exit == true)
				{
					if(Common.Debug) Log.e(TAG,"Readdata exit 2" + "dout=" + m_out_stream + ";din=" + m_in_stream + ";exit=" + exit);
					break; //未连接
				}
				len = m_in_stream.available();
				if(len > 0)
				{
					m_in_stream.read(Precv,all_len,len);
					all_len += len;
					if(Common.Debug) Log.i(TAG,"Read:" + Commonfunc.bytesToHexString(Precv, 0,len));
					if((all_len == 9) && (Precv[5] == 0x03)) //收到下位机回复
					{
						//if(Common.Debug) Log.e(TAG,"Readdata exit 3");
						break;
					}
					else if(all_len > 9) //收到超过一帧,或者长帧
					{
						if(Precv[5] == 0x03) //表示是多帧
						{
							if((all_len - 9) == ((Precv[14] & 0xFF) + 6))
							{
								//if(Common.Debug) Log.e(TAG,"Readdata exit 4");
								break;
							}
						}
						else	//长帧
						{
							if(all_len == ((Precv[5] & 0xFF) + 6))
							{
								//if(Common.Debug) Log.e(TAG,"Readdata exit 5");
								break;
							}
						}
					}
				}
				endtime = System.currentTimeMillis();
				if(endtime  > (starttime + maxtime)) //超时
				{
					if(Common.Debug) Log.i(TAG,"超时退出!");
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(Common.Debug) Log.e(TAG,"接收异常");
		}
		return len;
	}
	//设置CAN线波特率
	public boolean SetCanBaud(long baud)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x06,0x10,0x03,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		if(m_log != null)
			m_log.PrintAppend(0,"SetBaud:" + baud);
		//获取波特率
		cmd[8] = (byte) ((baud / 0x10000) & 0xFF);
		cmd[9] = (byte) ((baud / 0x100) & 0xFF);
		cmd[10] = (byte) (baud & 0xFF);
		//计算校验
		cmd[11] = Commonfunc.CalcChechSum(cmd, 4, 11);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			return true;
		else
			return false;
	}
	//设置P-CAN或B-CAN
	public boolean SetCanMode(int mode)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x04,0x10,0x09,0x00,0x00};
		byte [] Ans = new byte[128];
		//记录设置CAN
		if(m_log != null)
			m_log.PrintAppend(0,"SetCan:" + mode);
		//
		cmd[8] = (byte) (mode & 0xFF);
		//计算校验
		cmd[9] = Commonfunc.CalcChechSum(cmd, 4, 9);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			return true;
		else
			return false;
	}
	//设置can过滤
	public boolean SetCanFilter(byte [] Pbuf,int num)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x08,0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		//记录设置CAN ID
		if(m_log != null)
		{
			m_log.PrintAppend(0,"SetCanID:" + Commonfunc.bytesToHexString(Pbuf, 0, num * 2));
			m_log.setCanId(Pbuf); //设置canID
		}
		//
		cmd[8] = (byte) (num & 0xFF);
		for(int i = 0; i < num * 2; i ++)
		{
			cmd[9 + i] = Pbuf[i];
		}
		//计算校验
		cmd[9 + num*2] = Commonfunc.CalcChechSum(cmd, 4, 9 + num * 2);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			return true;
		else
			return false;
	}
	public boolean SetStandCanAutoFrame(int Pid,byte [] Pbuf,int Plen)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x0D,0x10,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		cmd[8] = (byte) (Pid / 0x100);
		cmd[9] = (byte) (Pid &0xFF);
		for(int i = 0; i < Plen; i ++)
		{
			cmd[10 + i] = Pbuf[i];
		}
		//¼ÆËãÐ£Ñé
		cmd[10 + Plen] = Commonfunc.calcuCheckCode(cmd, 4, 10 + Plen);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
		{
			if(m_log != null) m_log.printMessage(0,"SetAutoCmd:" + Pid + ":" + Commonfunc.bytesToHexString(Pbuf, 0, Plen));
			return true;
		}
		else
			return false;
	}
	//设置can自动回复
	public boolean SetCanAutoFrame(byte [] Pbuf,int Plen)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x0B,0x10,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		for(int i = 0; i < Plen; i ++)
		{
			cmd[8 + i] = Pbuf[i];
		}
		//计算校验
		cmd[8 + Plen] = Commonfunc.CalcChechSum(cmd, 4, 8 + Plen);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			return true;
		else
			return false;
	}
	//设置时序
	public boolean SetCommunTimer(int P1,int P2,int P3,int P4)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x09,0x10,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		cmd[8] = (byte) (P1 & 0xFF);
		cmd[9] = (byte) ((P2 / 0x100) & 0xFF);
		cmd[10] = (byte) (P2 & 0xFF);
		cmd[11] = (byte) ((P3 / 0x100) & 0xFF);
		cmd[12] = (byte) (P3 & 0xFF);
		cmd[13] = (byte) (P4 & 0xFF);
		//计算校验
		cmd[14] = Commonfunc.CalcChechSum(cmd, 4, 14);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			return true;
		else
			return false;
	}
	//KWP波特率设置
	public boolean SetKwpBaud(long baud,int kwpmode)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x06,0x10,0x02,0x00,0x00,0x02,0x00};
		byte [] Ans = new byte[128];
		if(m_log != null)
			m_log.PrintAppend(0,"SetkwpBaud:" + baud);
		//获取波特率
		cmd[8] = (byte) ((baud / 0x100) & 0xFF);
		cmd[9] = (byte) (baud & 0xFF);
		//设置KWP模式
		cmd[10] = (byte) kwpmode;
		//计算校验
		cmd[11] = Commonfunc.CalcChechSum(cmd, 4, 11);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			return true;
		else
			return false;
	}
	//获取序列号
	public boolean GetSerialNum(byte [] Serialnum,int Psize,byte[] softver)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x03,0x20,0x08,0x00};
		byte [] Ans = new byte[128];
		//计算校验
		cmd[8] = Commonfunc.CalcChechSum(cmd, 4, 8);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
		{
			System.arraycopy(Ans, 8, Serialnum, 0, 12);
			System.arraycopy(Ans, 22, softver, 0, 2);
			return true;
		}
		else
			return false;
	}
	//cmd使用can重发3次,发多帧收多帧
	public int CanSendAndRecvN2N(byte [] Send,int Plen,byte [] Recv,int Psize,int errorcode,int maxtime)
	{
		int error = 0;
		byte [] Readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			iRet = CanSendMore2More(Send,Plen,Readbuf,Readbuf.length,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= Common.cmd_freq) return 5001; //无响应
		if ((Readbuf[1]&0xFF) == ((Send[1] + 0x40)&0xFF)) //判断结果
		{
			error = 0;
		}
		else
		{
			error = errorcode;
		}
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		if(iRet > 0x200 || iRet < 1) return error;
		System.arraycopy(Readbuf, 0, Recv, 0, iRet);
		return error;
	}
	public int CanSendAndRecvO2O(int Psid,int Prid,byte [] Send,int Plen,byte [] Recv,int Psize,int errorcode,int maxtime)
	{
		int error = 0;
		byte [] Readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			iRet = CanSendOne2One(Psid,Prid,Send,Plen,Readbuf,Readbuf.length,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= Common.cmd_freq) return 5001; //无响应
		if (Readbuf[1] == (Send[1] + 0x40)) //判断结果
		{
			error = 0;
		}
		else
		{
			error = errorcode;
		}
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		System.arraycopy(Readbuf, 0, Recv, 0, iRet);
		return error;
	}
	//CAN发一帧收一帧，不判断返回值
	public int CanSendAndRecvO2O_Spec(int Psid,int Prid,byte [] Send,int Plen,byte [] Recv,int Psize,int errorcode,int maxtime)
	{
		int error = 0;
		byte [] Readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			iRet = CanSendOne2One(Psid,Prid,Send,Plen,Readbuf,Readbuf.length,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= Common.cmd_freq) return 5001; //无响应
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		System.arraycopy(Readbuf, 0, Recv, 0, iRet);
		return error;
	}
	//cmd使用can重发3次,发多帧收多帧
	public int CanSendAndRecvN2N_LongTime(byte [] Send,int Plen,byte [] Recv,int Psize,int errorcode,int maxtime)
	{
		int error = 0;
		byte [] Readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			iRet = CanSendMore2More_LongTime(Send,Plen,Readbuf,Readbuf.length,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= Common.cmd_freq) return 5001; //无响应
		if (Readbuf[1] == (Send[1] + 0x40)) //判断结果
		{
			error = 0;
		}
		else
		{
			error = errorcode;
		}
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		System.arraycopy(Readbuf, 0, Recv, 0, iRet);
		return error;
	}

	//cmd CAN 发多帧收多帧
	private int CanSendMore2More(byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x31};
		byte [] data = new byte[256];
		//记录发送的数据
		if(m_log != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			m_log.PrintAppend(1,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(Plen <= 8) //单帧
		{
			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < Plen; i ++)
			{
				data[3 + i] = send[i];
			}
		}
		else	//多帧
		{
			framenum = (Plen + 6) / 7;
			if (framenum > 25) //越界
			{
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++)
			{
				//添加帧头
				if (i == 0)
					data[3 +i * 8] = 0x10;
				else
					data[3 +i * 8] = (byte) (0x20 + i % 0x10);
				//添加内容
				for (int j = 0; j < 7; j ++)
				{
					data[3 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			//帧头
			data[3 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = Plen % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++)
			{
				data[3 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		//获取帧数
		data[2] = (byte)framenum;
		//组合成命令
		byte [] Sendbuf = new byte [256];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[256];
		//int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		int iRet =SendOneToOneNew(Sendbuf, Sendlen, Readbuf, Readbuf.length, maxtime);
		if(iRet != 9) //nok
		{
			if(iRet >= 0) //
				iRet = -5;
			return iRet;
		}
		//接收数据
		while(true)
		{
			iRet = ReaddataComplete(Readbuf, Readbuf.length, maxtime + 500);
			if(iRet > 9) //ok
			{
				if((Readbuf[5] == 0x0D) && (Readbuf[10] == 0x03) && (Readbuf[11] == 0x7F) && (Readbuf[13] == 0x78)) //wait
				{
					if(m_log != null){
						m_log.PrintAppend(2,Commonfunc.bytesToHexString(Readbuf, 10, 14));
					}
					Sleep(10);
					continue;
				}
				else //拷贝数据
				{
					//拆开CAN包重组CAN数据
					if((Readbuf[8]&0xFF) > 25) break;
					if (Readbuf[8] == 1) //单帧
					{
						iRet = (Readbuf[10]&0xFF) + 1;
						for(int i = 0;i < iRet; i ++)
							recv[i] = Readbuf[10 + i];
					}
					else if (Readbuf[8] > 1) //多帧
					{
						iRet = ((Readbuf[10]&0x0F) << 8) + (Readbuf[11]&0xFF) + 1;
						for(int i = 0; i < Readbuf[8]; i ++)
						{
							System.arraycopy(Readbuf,9 + i * 9 + 2, recv, i * 7, 7);
						}
					}
					break;
				}
			}
			else if(iRet == 9 && Readbuf[6] == 0x6F && Readbuf[7] == 0x02) //timeout
			{
				iRet = -2; break;
			}
			else
				break;
		}
		//记录接收的数据
		if(m_log != null && iRet > 0){
			String result=Commonfunc.bytesToHexString(recv, 0, iRet);
			m_log.PrintAppend(2,result);
		}
		return iRet;
	}
	//cmd CAN 发多帧收多帧刷写
	private int CanSendMore2More_long(byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x33};
		byte [] data = new byte[5120];
		//记录发送的数据
		if(m_log != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			m_log.PrintAppend(1,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(Plen <= 8) //单帧
		{
			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < Plen; i ++)
			{
				data[3 + i] = send[i];
			}
		}
		else	//多帧
		{
			framenum = (Plen + 6) / 7;
			if (framenum > 600) //越界
			{
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++)
			{
				//添加帧头
				if (i == 0)
					data[4 +i * 8] = 0x10;
				else
					data[4 +i * 8] = (byte) (0x20 + i % 0x10);
				//添加内容
				for (int j = 0; j < 7; j ++)
				{
					data[4 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			//帧头
			data[4 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = Plen % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++)
			{
				data[4 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		//获取帧数
		data[2] = (byte)(framenum / 0x100);
		data[3] = (byte)(framenum % 0x100);
		//组合成命令
		byte [] Sendbuf = new byte [5120];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 4, Sendbuf);
		if(Common.Debug)
		{
			//Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			//Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1) //单帧
						{
							iRet = Readbuf[10] + 1;
							for(int i = 0;i < iRet; i ++)
								recv[i] = Readbuf[10 + i];
						}
						else if (Readbuf[8] > 1) //多帧
						{
							iRet = Readbuf[11] + 1;
							int j;
							for(int i = 0; i < Readbuf[8]; i ++)
							{
								for (j = 0; j < 7; j ++)
								{
									recv[i * 7 + j] = Readbuf[9 + i * 9 + 2 + j];
								}
							}
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1) //单帧
				{
					iRet = Readbuf[19] + 1;
					for(int i = 0;i < iRet; i ++)
						recv[i] = Readbuf[19 + i];
				}
				else if (Readbuf[17] > 1) //多帧
				{
					iRet = Readbuf[20] + 1;
					int j;
					for(int i = 0; i < Readbuf[17]; i ++)
					{
						for (j = 0; j < 7; j ++)
						{
							recv[i * 7 + j] = Readbuf[18 + i * 9 + 2 + j];
						}
					}
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(m_log != null && iRet > 0){
			String result=Commonfunc.bytesToHexString(recv, 0, iRet);
			m_log.PrintAppend(2,result);
		}
		return iRet;
	}
	//CAN发一帧收一帧
	private int CanSendOne2One(int Psid,int Prid,byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x32};
		byte [] data = new byte[128];
		//记录发送的数据
		if(m_log != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			m_log.PrintAppend(Psid,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		//send id
		data[2] = (byte) ((Psid >>> 8) & 0xFF);
		data[3] = (byte) (Psid &0xFF);
		//recv id
		data[4] = (byte) ((Prid >>> 8) & 0xFF);
		data[5] = (byte) (Prid &0xFF);
		//特征报文
		data[6] = 0x00;
		data[7] = 0x01;
		data[8] = (byte) 0xFF;
		//data 8bytes
		System.arraycopy(send, 0, data, 9, Plen);

		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, 17, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1) //单帧
						{
							iRet = 8;
							for(int i = 0;i < 8; i ++)
								recv[i] = Readbuf[10 + i];
						}
						else if (Readbuf[8] > 1) //多帧
						{
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1) //单帧
				{
					iRet = 8;
					for(int i = 0;i < 8; i ++)
						recv[i] = Readbuf[19 + i];
				}
				else if (Readbuf[17] > 1) //多帧
				{
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(m_log != null && iRet > 0){
			m_log.PrintAppend(Prid,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}
	//CAN发一帧收一帧
	private int CanSendOne2One_New(byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x32};
		byte [] data = new byte[128];
		//记录发送的数据
		if(m_log != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			m_log.PrintAppend(1,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(Plen <= 8) //单帧
		{
			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < Plen; i ++)
			{
				data[3 + i] = send[i];
			}
		}
		else	//多帧
		{
			framenum = (Plen + 6) / 7;
			if (framenum > 15) //越界
			{
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++)
			{
				//添加帧头
				if (i == 0)
					data[3 +i * 8] = 0x10;
				else
					data[3 +i * 8] = (byte) (0x20 + i % 0x10);
				//添加内容
				for (int j = 0; j < 7; j ++)
				{
					data[3 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			//帧头
			data[3 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = Plen % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++)
			{
				data[3 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		//获取帧数
		data[2] = (byte)framenum;
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1) //单帧
						{
							iRet = 8;
							for(int i = 0;i < 8; i ++)
								recv[i] = Readbuf[10 + i];
						}
						else if (Readbuf[8] > 1) //多帧
						{
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1) //单帧
				{
					iRet = 8;
					for(int i = 0;i < 8; i ++)
						recv[i] = Readbuf[19 + i];
				}
				else if (Readbuf[17] > 1) //多帧
				{
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(m_log != null && iRet > 0){
			m_log.PrintAppend(2,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}
	//cmd CAN 发多帧收多帧,特殊处理超长时间收数据
	private int CanSendMore2More_LongTime(byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x31};
		byte [] data = new byte[128];
		//记录发送的数据
		if(m_log != null){
			m_log.PrintAppend(1,Commonfunc.bytesToHexString(send, 0, Plen));
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(Plen <= 8) //单帧
		{
			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < Plen; i ++)
			{
				data[3 + i] = send[i];
			}
		}
		else	//多帧
		{
			framenum = (Plen + 6) / 7;
			if (framenum > 15) //越界
			{
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++)
			{
				//添加帧头
				if (i == 0)
					data[3 +i * 8] = 0x10;
				else
					data[3 +i * 8] = (byte) (0x20 + i % 0x10);
				//添加内容
				for (int j = 0; j < 7; j ++)
				{
					data[3 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			//帧头
			data[3 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = Plen % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++)
			{
				data[3 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		//获取帧数
		data[2] = (byte)framenum;
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, maxtime + 20000);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1) //单帧
						{
							iRet = Readbuf[10] + 1;
							for(int i = 0;i < iRet; i ++)
								recv[i] = Readbuf[10 + i];
						}
						else if (Readbuf[8] > 1) //多帧
						{
							iRet = Readbuf[11] + 1;
							int j;
							for(int i = 0; i < Readbuf[8]; i ++)
							{
								for (j = 0; j < 7; j ++)
								{
									recv[i * 7 + j] = Readbuf[9 + i * 9 + 2 + j];
								}
							}
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1) //单帧
				{
					iRet = Readbuf[19] + 1;
					for(int i = 0;i < iRet; i ++)
						recv[i] = Readbuf[19 + i];
				}
				else if (Readbuf[17] > 1) //多帧
				{
					iRet = Readbuf[20] + 1;
					int j;
					for(int i = 0; i < Readbuf[17]; i ++)
					{
						for (j = 0; j < 7; j ++)
						{
							recv[i * 7 + j] = Readbuf[18 + i * 9 + 2 + j];
						}
					}
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(m_log != null && iRet > 0){
			String result =Commonfunc.bytesToHexString(recv, 0, iRet);
			m_log.PrintAppend(2,result);
		}
		return iRet;
	}
	//CAN只发一帧数据,返回1成功
	public int CanSendOneOnly(int SendId,byte[] send,int Plen)
	{
		byte [] cmd = new byte[]{0x11,0x39};
		byte [] data = new byte[128];
		//记录发送的数据
		if(m_log != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			m_log.PrintAppend(SendId,result);
		}
		data[0] = 0x01;  //can模式
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = (byte) (SendId / 0x100);
		data[4] = (byte) (SendId % 0x100);
		//添加发送命令的帧数以及帧内容
		System.arraycopy(send, 0, data, 5, Plen);
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, 13, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		if(iRet == 9) //只收到发送成功数据
		{
			iRet = 1;
		}
		else
			iRet = 0;
		return iRet;
	}
	public int CanOne2OneUDS(int Preq,int Pres,byte [] Send,int Plen,byte [] Recv,int Perror,int Pmaxtime,int Pfreq)
	{
		int error = 0;
		int i;
		for(i = 0; i < Pfreq; i ++)
		{
			error = CanOne2OneUDS(Preq,Pres,Send,Plen,Recv,Pmaxtime);
			if(error > 0) break;
			else if(error < 0)
			{
				error = 5002;
			}
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= Pfreq)
			error = 5001; //无响应
		return error;
	}
	//-1 -- 断网; -2 -- 超时; -3 -- IO异常; -4 -- 校验失败; -5 -- box异常
	private int CanOne2OneUDS(int Preq,int Pres,byte[] send,int Plen,byte [] recv,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x30};
		int framenum = 0;
		if(Plen > 20)
		{
			Sleep(1);
		}
		if(Plen <= 8)
		{
			framenum = 1;
		}
		else if(Plen <= 0x100)
		{
			framenum = (Plen + 6) / 7;
		}
		else
			framenum = (Plen + 5) / 7;
		byte [] data = new byte[10 + framenum * 8];
		Arrays.fill(data, (byte) 0);
		//记录发送的数据
		if(m_log != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			m_log.PrintAppend(Preq,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//send id
		data[2] = (byte) (Preq / 0x100);
		data[3] = (byte) (Preq % 0x100);
		//recv id
		data[4] = (byte) (Pres / 0x100);
		data[5] = (byte) (Pres % 0x100);
		//特征报文
		data[6] = 0;
		data[7] = 0;
		//添加发送命令的帧数以及帧内容
		data[8] = (byte) (framenum / 0x100);
		data[9] = (byte) (framenum % 0x100);
		//添加内容
		int k = 0;
		if(Plen <= 0x100) //1位长度
		{
			if(Plen <= 8)
			{
				System.arraycopy(send, 0, data, 10, Plen);
			}
			else
			{
				//第一帧
				data[10] = 0x10;
				System.arraycopy(send, 0, data, 11, 7);
				for(k = 1; k < framenum - 1; k ++)
				{
					data[10 + k * 8] = (byte) (0x20 + k % 0x10);
					System.arraycopy(send, k * 7, data, 11 + k * 8, 7);
				}
				//last
				k = (framenum - 1);
				data[10 + k * 8] = (byte) (0x20 + k % 0x10);
				int v_lastlen = Plen % 7;
				if(v_lastlen == 0)
					v_lastlen = 7;
				System.arraycopy(send, k * 7, data, 11 + k * 8, v_lastlen);
			}
		}
		else
		{
			//第一帧
			data[10] = (byte) (0x10 + send[0]);
			System.arraycopy(send, 1, data, 11, 7);
			for(k = 1; k < framenum - 1; k ++)
			{
				data[10 + k * 8] = (byte) (0x20 + k % 0x10);
				System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, 7);
			}
			//last
			k = (framenum - 1);
			data[10 + k * 8] = (byte) (0x20 + k % 0x10);
			int v_lastlen = (Plen - 1) % 7;
			if(v_lastlen == 0)
				v_lastlen = 7;
			System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, v_lastlen);
		}

		//组合成命令
		byte [] Sendbuf = new byte [9 + data.length];
		int Sendlen = addData2Cmd(cmd, data, data.length, Sendbuf);

		//发送
		byte [] Readbuf = new byte[512];
		//int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		int iRet =SendOneToOneNew(Sendbuf, Sendlen, Readbuf, Readbuf.length, maxtime);
		if(iRet != 9) //nok
		{
			if(iRet >= 0) //
				iRet = -5;
			return iRet;
		}
		//接收数据
		while(true)
		{
			iRet = ReaddataComplete(Readbuf, Readbuf.length, maxtime + 500);
			if(iRet > 9) //ok
			{
				if((Readbuf[5] == 0x0D) && (Readbuf[10] == 0x03) && (Readbuf[11] == 0x7F) && (Readbuf[13] == 0x78)) //wait
				{
					if(m_log != null){
						m_log.PrintAppend(Pres,Commonfunc.bytesToHexString(Readbuf, 10, 14));
					}
					if(maxtime < 5000)
						maxtime = 5000;
					Sleep(10);
					continue;
				}
				else //拷贝数据
				{
					//拆开CAN包重组CAN数据
					if((Readbuf[8]&0xFF) > 20) break;
					if (Readbuf[8] == 1) //单帧
					{
						iRet = Readbuf[10] + 1;
						for(int i = 0;i < iRet; i ++)
							recv[i] = Readbuf[10 + i];
					}
					else if (Readbuf[8] > 1) //多帧
					{
						iRet = ((Readbuf[10]&0x0F) << 8) + (Readbuf[11]&0xFF) + 1;
						for(int i = 0; i < Readbuf[8]; i ++)
						{
							System.arraycopy(Readbuf,9 + i * 9 + 2, recv, i * 7, 7);
						}
					}
					break;
				}
			}
			else if(iRet == 9 && Readbuf[6] == 0x6F && Readbuf[7] == 0x02) //timeout
			{
				iRet = -2; break;
			}
			else
				break;
		}

		//记录接收的数据
		if(m_log != null){
			if(iRet > 0)
				m_log.PrintAppend(Pres,Commonfunc.bytesToHexString(recv, 0, iRet));
			else
			{
				if(iRet == -1)
					m_log.PrintAppend(0, "Connect Lost!");
				else if(iRet == -2)
				{
					m_log.PrintAppend(0, "Time out!");
					iRet = 0;
				}
				else if(iRet == -3)
					m_log.PrintAppend(0, "IOException!");
				else  if(iRet == -4)
				{
					m_log.PrintAppend(0, "Check failed!");
					iRet = 0;
				}
				else  if(iRet == -5)
					m_log.PrintAppend(0, "Box error!");
				else
					m_log.PrintAppend(0, "Else error!");
			}
		}
		return iRet;
	}
	//KWP快速初始化
	public int KwpFastConnect(int baud,int kwpmode,byte[] send,int Plen,byte [] recv,int Psize,int maxtime,int testtimes,int errorcode)
	{
		int error = 0;
		int i,iRet = 0;
		//设置波特率
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			if(SetKwpBaud(baud,kwpmode) == true)
				break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		Sleep(Common.waittime);
		if(i == Common.cmd_freq) return 5001;
		//发送数据
		//先计算校验
		send[Plen - 1] = Commonfunc.CalcChechSum(send, 0, Plen - 1);
		byte [] Readbuf = new byte[256];
		for(i = 0; i <testtimes; i ++)
		{
			iRet = KwpFastInit((byte)0x19, (byte)0x19, send, Plen, Readbuf, Readbuf.length, maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= testtimes) return 5001;
		int r_Pos = 5;
		if((Readbuf[2]&0xFF) == 0x80) r_Pos ++; //当收到0x80开头的
		int s_Pos = 3;
		if((send[0]&0xFF) == 0x80) s_Pos ++;
		if (Readbuf[r_Pos] == (send[s_Pos] + 0x40)) //判断结果
		{
			error = 0;
		}
		else
		{
			error = errorcode;
		}
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		System.arraycopy(Readbuf, 0, recv, 0, iRet);
		return error;
	}
	//KWP快速初始化
	private int KwpFastInit(byte Plow,byte Phih,byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x01};
		byte [] data = new byte[128];
		//记录发送的数据
		if(m_log != null){
			m_log.PrintAppend(1,Commonfunc.bytesToHexString(send, 0, Plen));
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//拉低拉高时间
		data[2] = Plow;
		data[3] = Phih;
		//添加发送命令
		System.arraycopy(send, 0, data, 4, Plen);
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, Plen + 4, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, Common.cmdmaxtime);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开数据
						recv[0] = 0x01;
						recv[1] = (byte) iRet;
						System.arraycopy(Readbuf, 8, recv, 2, iRet);
						iRet += 2;
					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开数据
				recv[0] = 0x01;
				recv[1] = (byte) iRet;
				System.arraycopy(Readbuf, 17, recv, 2, iRet);
				iRet += 2;
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(m_log != null && iRet > 0){
			m_log.PrintAppend(2,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}
	//KWP快速初始化
	public int KwpOneToOne(byte[] send,int Plen,byte [] recv,int Psize,int maxtime,int testtimes,int errorcode)
	{
		int error = 0;
		int i,iRet = 0;
		//发送数据
		//先计算校验
		send[Plen - 1] = Commonfunc.CalcChechSum(send, 0, Plen - 1);
		byte [] Readbuf = new byte[256];
		for(i = 0; i <testtimes; i ++)
		{
			iRet = KwpSendOne2One(send, Plen, Readbuf, Readbuf.length, maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= testtimes) return 5001;
		int r_Pos = 5;
		if((Readbuf[2]&0xFF) == 0x80) r_Pos ++; //当收到0x80开头的
		int s_Pos = 3;
		if((send[0]&0xFF) == 0x80) s_Pos ++;
		if ((Readbuf[r_Pos]&0xFF) == ((send[s_Pos]&0xFF) + 0x40)) //判断结果
		{
			error = 0;
		}
		else
		{
			error = errorcode;
		}
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		System.arraycopy(Readbuf, 0, recv, 0, iRet);
		return error;
	}
	//KWP快速初始化
	private int KwpSendOne2One(byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x02};
		byte [] data = new byte[128];
		//记录发送的数据
		if(m_log != null){
			m_log.PrintAppend(1,Commonfunc.bytesToHexString(send, 0, Plen));
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令
		System.arraycopy(send, 0, data, 2, Plen);
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, Plen + 2, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[256];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, Common.cmdmaxtime);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开数据
						recv[0] = 0x01;
						recv[1] = (byte) iRet;
						System.arraycopy(Readbuf, 8, recv, 2, iRet);
						iRet += 2;
					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开数据
				recv[0] = 0x01;
				recv[1] = (byte) iRet;
				System.arraycopy(Readbuf, 17, recv, 2, iRet);
				iRet += 2;
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(m_log != null && iRet > 0){
			String result=Commonfunc.bytesToHexString(recv, 0, iRet);
			m_log.PrintAppend(2,result);
		}
		return iRet;
	}


	/****************************蓝牙通信方法（结束）***************************************/

	public class BlueStateEvent{
		//预定义的几种蓝牙状态
		public static final int STATE_NONE = 		0; // 无连接
		public static final int STATE_LISTEN = 		1; // 监听状态
		public static final int STATE_CONNECTING = 	2; // 正在连接...
		public static final int STATE_CONNECTED = 	3; // 蓝牙已经连接.
		//蓝牙状态变量
		private int m_state = STATE_NONE;

		/** 设置State状态 */
		private void SetState(int state)
		{
			if (D)
				Log.d(TAG, "setState() " + "蓝牙State = " + state);
			m_state = state;
		}
		//设置蓝牙为监听状态
		public void SetListen()
		{
			SetState(STATE_LISTEN);
		}
		//设置为正在连接状态
		public void SetConnecting()
		{
			SetState(STATE_CONNECTING);
		}
		//设置为已经连接状态
		public void SetConnected()
		{
			SetState(STATE_CONNECTED);
		}
		//获取蓝牙状态
		public synchronized int GetBlueState()
		{
			return m_state;
		}
		//判断是否已经连接
		public boolean IsConnected()
		{
			if(m_state == STATE_CONNECTED)
				return true;
			else
				return false;
		}
		//判断是否正在连接
		public boolean IsConnecting()
		{
			if(m_state == STATE_CONNECTING)
				return true;
			else
				return false;
		}
		//判断是否连接中断
		public boolean IsConnectLost()
		{
			if(m_state == STATE_LISTEN || m_state == STATE_NONE)
				return true;
			else
				return false;
		}
	}
}
